package com.baoleme.service.impl;

import cn.hutool.crypto.digest.BCrypt;

import com.baoleme.dto.EmployeeLoginDTO;
import com.baoleme.dto.EmployeeModifyPasswordDTO;
import com.baoleme.dto.EmployeePageQueryDTO;
import com.baoleme.entity.Employee;
import com.baoleme.exceptions.BusinessException;
import com.baoleme.exceptions.enumeration.ResponseEnum;
import com.baoleme.mapper.EmployeeMapper;
import com.baoleme.service.EmployeeService;
import com.baoleme.utils.JwtUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import jakarta.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wuyunbin
 * @since 2024-09-13
 */
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {

    @Resource
    JwtUtils jwtUtils;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Map<String, String> login(EmployeeLoginDTO employeeLoginDTO) {
        //2.构造条件
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(Employee::getUsername, employeeLoginDTO.getUsername());
//                .or()
//                .eq(Employee::getPassword, employee.getPassword());

        //1. 根据用户名或者密码查询用户信息
        Employee employeeInDb = this.getOne(wrapper);

        //判断是否查到用户
        if (employeeInDb == null) {
            throw new BusinessException(ResponseEnum.INVALID_ACCOUNT);
        }
        if(employeeInDb.getStatus()==0){
            throw  new BusinessException(ResponseEnum.ERROR_DISABLED_ACCOUNT);
        }

        //比较密码
        if (!BCrypt.checkpw(employeeLoginDTO.getPassword(), employeeInDb.getPassword())) {

            throw new BusinessException(ResponseEnum.INVALID_ACCOUNT);
        }

        //签发token


        Claims claims= Jwts.claims();
        claims.put("id",employeeInDb.getId());
        String refreshToken = this.creatToken(claims, 60 * 60 * 2L);
        claims.put("username",employeeInDb.getUsername());
        claims.put("password",employeeInDb.getPassword());
        String accessToken = this.creatToken(claims, 60L);
        Map<String, String> tokens = new HashMap<>();
        tokens.put("accessToken", accessToken);
        tokens.put("refreshToken", refreshToken);
        return tokens;
    }

    @Override
    public boolean modifyPassword(EmployeeModifyPasswordDTO employeeModifyPasswordDTO) {
        Employee employee=this.getById(employeeModifyPasswordDTO.getId());

        if(!BCrypt.checkpw(employeeModifyPasswordDTO.getOldPassword(),employee.getPassword())){

            throw new BusinessException(ResponseEnum.ERROR_OLD_PASSWORD);

        }
        String newPassword= BCrypt.hashpw(employeeModifyPasswordDTO.getNewPassword());
        employee.setPassword(newPassword);

        return this.updateById(employee);
    }

    @Override
    public boolean saveEmployee(Employee employee) {

        //编写查询条件
        LambdaQueryWrapper<Employee> wrapper=new LambdaQueryWrapper();
        wrapper.eq(Employee::getUsername,employee.getUsername())
                .or()
                .eq(Employee::getIdNumber,employee.getIdNumber())
                .or()
                .eq(Employee::getPhone,employee.getPhone());
        //将查询条件放进查询中
        long count = this.count(wrapper);

        //比对查询条件如果存在重复将直接跳出
        if(count>0){
            throw new BusinessException(ResponseEnum.DUPLICATE_DATA);
        }

        //将密码加密后存入数据库
        employee.setPassword(BCrypt.hashpw(employee.getPassword()));
        //将新员工信息存入数据库
        boolean save = this.save(employee);

        return save;




    }

    @Override
    public boolean status(Employee employee) {
        //查询当前对象
        Employee e = this.getById(employee.getId());
        e.setStatus(employee.getStatus());

        return this.updateById(e);
    }

    @Override
    public IPage<Employee> getPage(EmployeePageQueryDTO employeePageQueryDTO) {
        IPage<Employee> pageInfo=new Page<>(employeePageQueryDTO.getCurrent(),employeePageQueryDTO.getPageSize());
        return this.page(pageInfo);
    }

    @Override
    public boolean logout(String username) {
        //2.构造条件
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUsername, username);


        //1. 根据用户名或者密码查询用户信息
        Employee employeeDb = this.getOne(wrapper);

        //判断是否得到用户
        if (employeeDb == null) {
            throw new BusinessException(ResponseEnum.INVALID_ACCOUNT);
        }

        redisTemplate.delete(employeeDb.getUsername());

        return true;
    }

    private String creatToken(Claims claims,Long ttl) {
        return jwtUtils.createJwt((String) claims.get("id"), claims, ttl, "123456789123456789123456789123456789123456789123456789123456789123456789123456789");
    }

}
